package com.lccviolet;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author LiChaochao
 * @Date 2021/10/29 14:18
 * @Description LRU算法：最近最少使用，选择最近最久未使用的数据淘汰
 *              哈希 + 链表实现 LinkedHashMap
 *              只要读或使用数据，就将该数据重新排到最前面（true）
 */
public class LRUCacheDemo<K, V> extends LinkedHashMap<K, V> {

    private int capacity; // 缓存坑位

    public LRUCacheDemo(int capacity) {
        /*
         * accessOrder:the ordering mode
         *      true:for access-order，访问顺序，即使用频率
         *      false:for insertion-order，插入顺序
         * */
        super(capacity, 0.75F, true);
        this.capacity = capacity;
    }

    /*
     * 必须重写该方法，才能实现功能。否则指定缓存长度没用，会一直往进put数据，而不会淘汰
     * */
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return super.size() > capacity;
    }

    /*
        true：          false:
        [1, 2, 3]       [1, 2, 3]
        [2, 3, 4]       [2, 3, 4]
        [2, 4, 3]       [2, 3, 4]
        [4, 3, 2]       [2, 3, 4]
        [3, 2, 5]       [3, 4, 5]
    */
    public static void main(String[] args) {
        LRUCacheDemo<Object, Object> lruCacheDemo = new LRUCacheDemo<>(3);
        lruCacheDemo.put(1, "a");
        lruCacheDemo.put(2, "b");
        lruCacheDemo.put(3, "c");

        System.out.println(lruCacheDemo.keySet());

        lruCacheDemo.put(4, "d");
        System.out.println(lruCacheDemo.keySet());

        // "3"又进来一次
        lruCacheDemo.put(3, "c");
        System.out.println(lruCacheDemo.keySet());

        // 使用“2”
        lruCacheDemo.get(2);
        System.out.println(lruCacheDemo.keySet());

        lruCacheDemo.put(5, "e");
        System.out.println(lruCacheDemo.keySet());
    }
}
